package com.xdq.serviceedu.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.spire.presentation.Comment;
import com.spire.presentation.ISlide;
import com.spire.presentation.Presentation;
import com.xdq.commonutils.R;
import com.xdq.serviceedu.entity.vo.ModelConfigVo;
import com.xdq.serviceedu.entity.vo.PPTRemakesVo;
import com.xdq.serviceedu.entity.vo.PptImageVo;
import com.xdq.serviceedu.utils.HttpClientUtil;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/eduservice/ppt")
@CrossOrigin // 解决跨域
@Slf4j
public class EduPPTController {


    private Map<String, String> inferenceMap = new HashMap<>();

    @PostMapping("sendImage")
    public R sendImage(@RequestBody PptImageVo pptImageVo) {
        System.out.println("请求体" + pptImageVo);
        String sendData = JSONObject.toJSONString(pptImageVo);
        System.out.println("发送数据："+sendData);
        String s = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Send_Image_Url", sendData);
        Map jsonMap = JSON.parseObject(s);
//        Map jsonMap = (Map) JSONObject.toJSON(s);
        System.out.println("接收数据：" + jsonMap);
        return R.ok().data(jsonMap);
    }

    @PostMapping("sendConfig")
    public R sendConfig(@RequestBody ModelConfigVo modelConfigVo) {
        String index = modelConfigVo.getVitis().getIndex();
        String user = modelConfigVo.getVitis().getUser();
        Map vitisMap = new HashMap<>();
        vitisMap.put("User", user);
        vitisMap.put("Index", index);
        String sendData = JSONObject.toJSONString(vitisMap);
        String s = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Send_Select_VITS_Model", sendData);
        Map jsonMap = JSON.parseObject(s);
        if(!jsonMap.get("result").equals("Failed")) {
            String enhancer = modelConfigVo.getSadtalk().getEnhancer();
            Float scale = modelConfigVo.getSadtalk().getScale();
            Map sadtalkerMap = new HashMap<>();
            sadtalkerMap.put("enhancer", enhancer);
            sadtalkerMap.put("expression_scale", scale);
            Map sendMap = new HashMap<>();
            sendMap.put("User", modelConfigVo.getUser());
            sendMap.put("VITS_Config", vitisMap);
            sendMap.put("SadTalker_Config", sadtalkerMap);
            String sendData2 = JSONObject.toJSONString(sendMap);
            String s2 = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Send_Config", sendData2);
            Map jsonMap2 = JSON.parseObject(s2);
            return R.ok().data(jsonMap2);
        }
        return R.error();
    }



    @PostMapping("sendPPTReamkes")
    public R sendPPTReamkes(MultipartFile file, String user) throws Exception {

        // 将文件保存在服务器目录中
        // 文件名称
//            String uuid = UUID.randomUUID().toString();
        // 得到上传文件后缀
        String originalName = file.getOriginalFilename();
//            String ext = "." + FilenameUtils.getExtension(originalName);
        // 新生成的文件名称
//            String fileName = uuid + ext;
        // 复制文件
        String dir = "D:\\JavaCodeIDEA\\DigitalHuman\\Digital_Human_API-main\\Data\\" + user;
        File targetFile = new File(dir, originalName);
        FileUtils.writeByteArrayToFile(targetFile, file.getBytes());

        String filepath = dir+ "\\" +originalName;
        //加载PPT测试文档
        Presentation ppt = new Presentation();
        ppt.loadFromFile(filepath);

        Map sendMap = new HashMap<>();
        sendMap.put("User", user);
        Map remakesMap = new HashMap<>();
        for (int i = 0; i < ppt.getSlides().size(); i++) {
            //获取指定幻灯片(第2张）
            ISlide slide = ppt.getSlides().get(i);

            //获取幻灯片中的第一个批注
            Comment comment = slide.getComments()[0];
            String author = comment.getAuthorName();
            String commenttext = comment.getText();
            Date time = comment.getDateTime();

            //输出获取的批注内容
            System.out.println( "批注作者：" + author + "\n"
                    + "添加批注时间：" + time + "\n"
                    + "批注内容：" + commenttext + "\n");
            remakesMap.put(String.valueOf(i), commenttext);
        }
        sendMap.put("PPT_Remakes", remakesMap);
        String sendData = JSONObject.toJSONString(sendMap);
        String s = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Send_PPT_Remakes", sendData);
        Map jsonMap = JSON.parseObject(s);
        return R.ok().data(jsonMap);
    }

    @PostMapping("getInferenceState")
    public R getInferenceState(String user) {
        if (!inferenceMap.containsKey(user)) {
            inferenceMap.put(user, "Running");
            new Thread(new Runnable() {
                @Override
                public void run() {
                    getInference(user);
                }
            }).start();
            return R.ok().message("Running");
        }
        return R.ok().message(inferenceMap.get(user));
    }

    @PostMapping("getInference")
    public R getInference(String user)  {
        try {
            // 推理
            Map sendMap = new HashMap<>();
            sendMap.put("User", user);
            String sendData = JSONObject.toJSONString(sendMap);
            String s = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Get_Inference", sendData);
            Map jsonMap = JSON.parseObject(s);
            String task = (String) jsonMap.get("result");

            Map sendMap2 = new HashMap<>();
            sendMap2.put("User", user);
            sendMap2.put("Task", task);
            String sendData2 = JSONObject.toJSONString(sendMap2);
            // 获取状态
            for (int i = 0; i < 10; i++) {
                Thread.sleep(5000);
                String s2 = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Get_State", sendData2);
                Map jsonMap2 = JSON.parseObject(s2);
                if (jsonMap.get("result").equals("True")) {
                    System.out.println("任务完成：" + task);
                    break;
                }
            }

            // 音频时长
            String s3 = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Recive_Wav_Time", sendData);
            Map jsonMap3 = JSON.parseObject(s3);
            System.out.println("获取的音频时长信息：" + jsonMap3.get("result"));

            // 音频与视频合并
            String s4 = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/PPT_Video_Merge", sendData);
            Map jsonMap4 = JSON.parseObject(s4);
            String task4 = (String) jsonMap4.get("result");
            Map sendMap4 = new HashMap<>();
            sendMap4.put("User", user);
            sendMap4.put("Task", task4);
            String sendData4 = JSONObject.toJSONString(sendMap4);
            // 获取状态
            for (int i = 0; i < 10; i++) {
                Thread.sleep(5000);
                String state = HttpClientUtil.sendJsonPost("http://127.0.0.1:5000/Get_State", sendData4);
                Map stateMap = JSON.parseObject(state);
                if (stateMap.get("result").equals("True")) {
                    System.out.println("任务完成：" + task);
                    break;
                }
            }

            String lastPath = "D:\\JavaCodeIDEA\\DigitalHuman\\Digital_Human_API-main\\Data\\" + user + "\\last_video.mp4";
            File targetFile = new File(lastPath);
            if (targetFile.exists()) {
                inferenceMap.put(user, "Success");
                return R.ok().message("合成成功");
            }
            inferenceMap.put(user, "Failed");
            return R.error().message("合成失败");
        } catch (InterruptedException e) {
            inferenceMap.put(user, "Failed");
            return R.error().message(e.getMessage());
        }
    }

    /**
     * @param user     用户名，也对应着存放路径
     * @param response
     * @功能描述 下载文件:将输入流中的数据循环写入到响应输出流中，而不是一次性读取到内存
     */
    @PostMapping("/download")
    public void downloadLocal(String user, HttpServletResponse response) {
        if (StringUtils.isEmpty(user)) {
            return;
        }
        String path = "D:\\JavaCodeIDEA\\DigitalHuman\\Digital_Human_API-main\\Data\\" + user + "\\last_video.mp4";
        try {
            // path是指想要下载的文件的路径
            File file = new File(path);
            // 获取文件名
            String fileName = file.getName();
            // 获取文件的后缀名
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();
            // 以流的形式下载文件
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes()));
            response.addHeader("Content-length", "" + file.length());

            // 设置跨域支持 这里如果不设置，swagger和postman可以正常访问，但是前端vue页面无法访问
            response.setHeader("Access-Control-Allow-Origin","*");
            response.setHeader("Access-Control-Allow-Method","POST,GET,OPTIONS");
            response.setHeader("Access-Control-Allow-Headers","*");

            BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            bos.write(buffer);
            bos.flush();
            bos.close();
            log.info("fileDownSuccessful...");
        } catch (IOException e) {
            log.error("fileDownFail...", e);
            e.printStackTrace();
        }

    }

}
